﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace OD.ProjectCustomizationTool.Helpers
{
    internal sealed class FlatProjectFileUpdateMonitor : IDisposable
    {
        private readonly ProjectToolBase source;
        private readonly XDocument document;

        #region IDisposable Members

        // This code has been generated from the 'dispose' custom snippet.

        /// <summary>
        ///Track whether Dispose has been called. 
        /// </summary>
        private Boolean isDisposed; // = false;

        /// <summary>
        /// Implement IDisposable.
        /// Do not make this method virtual.
        /// A derived class should not be able to override this method.
        /// <see cref="ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.fr/fxref_mscorlib/html/d2fe234e-d59b-fa98-3f28-f6f3f75757e3.htm"/>
        /// <see cref="ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.fr/dv_vsetsa03/html/12afb1ea-3a17-4a3f-a1f0-fcdb853e2359.htm"/>
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Dispose(bool disposing) executes in two distinct scenarios.
        /// If disposing equals true, the method has been called directly
        /// or indirectly by a user's code. Managed and unmanaged resources
        /// can be disposed.
        /// If disposing equals false, the method has been called by the
        /// runtime from inside the finalizer and you should not reference
        /// other objects. Only unmanaged resources can be disposed.
        /// </summary>
        private void Dispose(Boolean disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.isDisposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    var fileContent = this.document.ToString();
                    fileContent = fileContent.Replace("xmlns=\"\"", String.Empty);
                    File.WriteAllText(this.source.FullPathToProj, fileContent);
                }

                // Note disposing has been done.
                this.isDisposed = true;
            }
        }

        #endregion

        internal FlatProjectFileUpdateMonitor(ProjectToolBase source)
        {
            if (source == null)
            {   // This code has been generated from the 'argnull' custom snippet.
                throw new ArgumentNullException("source");
            }

            this.source = source;

            this.document = XDocument.Load(this.source.FullPathToProj);
        }

        /// <summary>
        /// Retrieve the first conditionned property that matches an attribute pattern.
        /// </summary>
        /// <param name="conditionAttributePattern">The attribute pattern to search.</param>
        /// <returns>Returns the first XML element that matches the pattern.</returns>
        public XElement GetConditionnedProperty(String conditionAttributePattern)
        {
            return (from project in this.document.Elements()
                    from propertyGroup in project.Elements()
                    where String.Equals(propertyGroup.Name.LocalName, "PropertyGroup")
                    let conditionAttribute = propertyGroup.Attributes("Condition").FirstOrDefault()
                    where conditionAttribute != null && conditionAttribute.Value.Contains(conditionAttributePattern)
                    select propertyGroup).FirstOrDefault();
        }
    }
}
